Modul:Wikidata
module local variables local wiki = { langcode = mw.language.getContentLanguage().code } -- internationalisation local i18n = { "errors" = { "property-not-found" = "Eigenschaft nicht gefunden.", "entity-not-found" = "Entity nicht gefunden.", "unknown-claim-type" = "Unbekannter Aussagentyp.", "unknown-snak-type" = "Unbekannter Snak-Typ.", "unknown-datavalue-type" = "Unbekannter Datentyp.", "unknown-entity-type" = "Unbekannter Entity-Typ.", "qualifier-not-found" = "Qualifikator nicht gefunden." }, "somevalue" = "unbekannter Wert", "novalue" = "kein Wert" } local p = { } local function printError(code) return '' .. i18n.errorscode .. '' end function p.descriptionIn(frame) local langcode = frame.args1 -- return description of a Wikidata entity in the given language or the default language of this Wikipedia site return mw.wikibase.getEntityObject().descriptionsor wiki.langcode.value end function p.labelIn(frame) local langcode = frame.args1 -- return label of a Wikidata entity in the given language or the default language of this Wikipedia site return mw.wikibase.getEntityObject().labelsor wiki.langcode.value end local function printDatavalueCoordinate(data, parameter) -- data fields: latitude double, longitude double, altitude double, precision double, globe URI, usually http://www.wikidata.org/entity/Q2 [earth] if parameter then if parameter "globe" then data.globe = mw.ustring.match(data.globe, "Q%d+") end -- extract entity id from the globe URI return dataparameter else return data.latitude .. "/" .. data.longitude -- combine latitude and longitude, which can be decomposed using the #titleparts wiki function end end local function printDatavalueQuantity(data, parameter) -- data fields: amount number, unit string, upperBound number, lowerBound number if parameter then return dataparamater else return tonumber(data.amount) end end local function printDatavalueTime(data, parameter) -- data fields: time 8601 time, timezone in minutes, before int, after int, precision int, calendarmodel URI -- precision: 0 - billion years, 1 - hundred million years, ..., 6 - millenia, 7 - century, 8 - decade, 9 - year, 10 - month, 11 - day, 12 - hour, 13 - minute, 14 - second -- calendarmodel: e.g. http://www.wikidata.org/entity/Q1985727 for the proleptic Gregorian calendar or http://www.wikidata.org/wiki/Q11184 for the Julian calendar] data.time = mw.text.trim(data.time, " +0") if parameter then if parameter "calendarmodel" then data.calendarmodel = mw.ustring.match(data.calendarmodel, "Q%d+") end -- extract entity id from the calendar model URI return dataparameter else return data.time end end local function printDatavalueEntity(data, parameter) -- data fields: entity-type string, numeric-id Wikidata id if parameter then return dataparameter else if data"entity-type" "item" then return mw.wikibase.label("Q" .. data"numeric-id") else printError("unknown-entity-type") end end end function findClaims(entity, property) if not property or not entity or not entity.claims then return end if mw.ustring.match(property, "^P%d+$") then -- if the property is given by an id (P..) access the claim list by this id return entity.claimsproperty else -- otherwise, iterate over all properties, fetch their labels and compare this to the given property name for k,v in pairs(entity.claims) do if mw.wikibase.label(k) property then return v end end return end end function getSnakValue(snak, parameter) -- snaks have three types: "novalue" for null/nil, "somevalue" for not null/not nil, or "value" for actual data if snak.snaktype "novalue" then return i18n"novalue" elseif snak.snaktype "somevalue" then return i18n"somevalue" elseif snak.snaktype ~= "value" then return nil, printError("unknown-snak-type") end -- call the respective snak parser if snak.datavalue.type "string" then return snak.datavalue.value elseif snak.datavalue.type "globecoordinate" then return printDatavalueCoordinate(snak.datavalue.value, parameter) elseif snak.datavalue.type "quantity" then return printDatavalueQuantity(snak.datavalue.value, parameter) elseif snak.datavalue.type "time" then return printDatavalueTime(snak.datavalue.value, parameter) elseif snak.datavalue.type "wikibase-entityid" then return printDatavalueEntity(snak.datavalue.value, parameter) else return nil, printError("unknown-datavalue-type") end end function getQualifierSnak(claim, qualifierId) -- a "snak" is Wikidata terminology for a typed key/value pair -- a claim consists of a main snak holding the main information of this claim, -- as well as a list of attribute snaks and a list of references snaks if qualifierId then -- search the attribute snak with the given qualifier as key if claim.qualifiers then local qualifier = claim.qualifiersqualifierId if qualifier then return qualifier1 end end return nil, printError("qualifier-not-found") else -- otherwise return the main snak return claim.mainsnak end end function getValueOfClaim(claim, qualifierId, parameter) local error local snak snak, error = getQualifierSnak(claim, qualifierId) if snak then return getSnakValue(snak, parameter) else return nil, error end end function p.claim(frame) local property = frame.args1 or "" local qualifierId = frame.args"qualifier" local parameter = frame.args"parameter" local list = frame.args"list" local showerrors = frame.args"showerrors" -- get wikidata entity local entity = mw.wikibase.getEntityObject() if not entity then if showerrors then return printError("entity-not-found") else return end end -- fetch the first claim of satisfying the given property local claims = findClaims(entity, property) if not claims or not claims1 then if showerrors then return printError("property-not-found") else return end end -- get initial sort indices local sortindices = {} for idx in pairs(claims) do sortindices+ 1 = idx end -- sort by claim rank local comparator = function(a, b) --local rankmap = { deprecated = -1, normal = 0, preferred = 1 } if not claimsa or not claimsb then return false end local ranka = claimsa.rank or "" local rankb = claimsb.rank or "" return not (ranka < rankb) --return ranka and rankb and rankmapranka >= rankmaprankb -- normal sort order is "<", but high priority needs to be sorted first (descending sort) --return mw.wikibase.label("Q" .. .mainsnak.datavalue.value"numeric-id") < mw.wikibase.label("Q" .. claimsb.mainsnak.datavalue.value"numeric-id") end table.sort(sortindices, comparator) local result local error if list then local value -- iterate over all elements and return their value (if existing) for idx = 1, #claims do value, error = getValueOfClaim(claims[sortindicesidx], qualifierId, parameter) if not value and showerrors then value = error end if result then if value then result = result .. list .. value end else result = value end end else -- return first element result, error = getValueOfClaim(claims[sortindices1], qualifierId, parameter) end if not result and showerrors then return error else return result end end function p.labelOf(frame) local id = frame.args1 -- returns the label of the given entity/property id -- if no id is given, the one from the entity associated with the calling Wikipedia article is used if not id then local entity = mw.wikibase.getEntityObject() if not entity then return printError("entity-not-found") end id = entity.id end return mw.wikibase.label(id) end function p.sitelinkOf(frame) local id = frame.args1 -- returns the Wikipedia article name of the given entity -- if no id is given, the one from the entity associated with the calling Wikipedia article is used if not id then local entity = mw.wikibase.getEntityObject() if not entity then return printError("entity-not-found") end id = entity.id end return mw.wikibase.sitelink(id) end function p.debug(frame) local status, err = pcall(p.claim, frame) return tostring(status) .. ", " .. tostring(err) end return p